//
// Copyright (c) 2013 Juan Palacios juan.palacios.puyana@gmail.com
// Subject to the BSD 2-Clause License
// - see < http://opensource.org/licenses/BSD-2-Clause>
//

#ifndef CONCURRENT_QUEUE_
#define CONCURRENT_QUEUE_
using namespace std;
#include <queue>
//#include <pthread.h>
#include "MsMutexLocker.h"
template<typename T>
class SyncQueue {

private:
	std::queue<T> queue_;
	MsMutexLocker* locker;
public:

	T pop() {
		MsAutoLock objLock(locker);
		T val = 0;
		if(queue_.empty()){
			val = 0;
		}else{
			val = (T)queue_.front();
			queue_.pop();
		}
		return val;
	}
	void push(const T& item) {
		MsAutoLock objLock(locker);
		queue_.push(item);

	}
	int size() {
		MsAutoLock objLock(locker);
		return queue_.size();
	}
	SyncQueue() {
		locker = new MsMutexLocker();
	}
	SyncQueue(const SyncQueue&) = delete;            // disable copying
	SyncQueue& operator=(const SyncQueue&) = delete; // disable assignment
	~SyncQueue() {
		if (locker != NULL) {
			delete(locker);
			locker = NULL;
		}
}
};

#endif



//#include "SyncQueue.h"
//#include <iostream>
//
//void* produce(void* q) {
//    for (int i = 0; i < 1000; ++i) {
//        ((SyncQueue<int>*) q)->push(i);
//    }
//    return 0;
//}
//
//void* consume(void* q) {
//    for (int i = 0; i < 1000; ++i) {
//        int item = ((SyncQueue<int>*) q)->pop();
//        printf("pop %d \n", item);
//    }
//    return 0;
//}